package org.csu.canteen.controller;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.csu.canteen.entity.*;
import org.csu.canteen.service.*;
import org.csu.canteen.service.Impl.CartServiceImpl;
import org.csu.canteen.vo.AccountVO;
import org.csu.canteen.vo.CouponPackageVO;
import org.csu.canteen.vo.IncludeMyListVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Controller
@RequestMapping("/account")
public class AccountController {

    @Autowired
    private CatalogService catalogService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private VerificationService verificationService;
    @Autowired
    private  CouponService couponService;
    @Autowired
    private LogService logService;
    @Autowired
    private CartService cartService;

    @Autowired
    public AccountController(VerificationService verificationService,CouponService couponService,LogService logService) {


    }

    @GetMapping("/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("image/png");

        // 生成验证码
        String verificationCode = verificationService.generateVerificationCode();

        // 存入 session
        request.getSession().setAttribute("verificationCode", verificationCode);

        // 生成验证码图片
        BufferedImage image = verificationService.generateImage(verificationCode);
        ImageIO.write(image, "png", response.getOutputStream());
    }

    @PostMapping("/verifyCaptcha")
    public String verifyCaptcha(@RequestParam String userInput, HttpSession session, RedirectAttributes redirectAttributes) {
        String correctCode = (String) session.getAttribute("verificationCode");

        if (correctCode == null) {
            redirectAttributes.addFlashAttribute("signOnMsg", "验证码已过期，请重新获取！");
            return "redirect:/account/signon";
        }

        if (userInput.equalsIgnoreCase(correctCode)) {
            session.removeAttribute("verificationCode"); // 验证成功后删除，避免重复使用
            return "redirect:/catalog/main"; // 成功后跳转到用户首页
        } else {
            redirectAttributes.addFlashAttribute("signOnMsg", "验证码输入错误！");
            return "redirect:/account/signon";
        }
    }

    @GetMapping("/edit")
    public String showEditAccountForm(Model model, HttpSession session) {
        AccountVO loginAccount = (AccountVO) session.getAttribute("loginAccount");
        if (loginAccount == null) {
            return "redirect:/account/signOn"; // 未登录，跳转回登录页
        }
        model.addAttribute("loginAccount", loginAccount);
        return "account/editAccount";
    }

    @PostMapping("/edit")
    public String editAccount(@ModelAttribute AccountVO account,
                              HttpSession session,
                              RedirectAttributes redirectAttributes) {
        try {
            accountService.updateAccount(account);

            // 更新 session 里的 loginAccount
            session.setAttribute("loginAccount", account);

            redirectAttributes.addFlashAttribute("successMessage", "Account updated successfully!");
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("signOnMsg", "Error updating account. Please try again.");
            return "redirect:/account/edit";
        }
        return "redirect:/account/edit";
    }

    @GetMapping("/account")
    public String showAccountInfo(@RequestParam("username") String username, Model model) {
        AccountVO loginAccount = accountService.getAccountByUsername(username);
        model.addAttribute("loginAccount", loginAccount);
        return "account/editAccount";
    }

    @PostMapping("/updateAccount")
    public String updateAccountInfo(@ModelAttribute AccountVO loginAccount, Model model) {
        accountService.updateAccount(loginAccount);
        model.addAttribute("loginAccount", loginAccount);
        return "account/editAccount";
    }

    @GetMapping("/register")
    public String showRegisterPage(Model model) {
        model.addAttribute("loginAccount", new AccountVO());
        return "account/register";
    }

    @PostMapping("/register")
    public String register(@ModelAttribute("loginAccount") AccountVO loginAccount,
                           @RequestParam("username") String username,
                           @RequestParam("password") String password,
                           @RequestParam("repeatPassword") String repeatPassword,
                           @RequestParam("firstName") String firstName,
                           @RequestParam("lastName") String lastName,
                           @RequestParam("email") String email,
                           @RequestParam("phone") String phone,
                           @RequestParam("address1") String address1,
                           @RequestParam(value = "address2", required = false) String address2,
                           @RequestParam("city") String city,
                           @RequestParam("zip") String zip,
                           @RequestParam("country") String country,
                           @RequestParam("verificationCode") String verificationCode,
                           @RequestParam("state") String state,
                           @RequestParam("favouriteCategoryId") String favouriteCategoryId,
                           @RequestParam("listOption1") int listOption1,
                           @RequestParam("bannerOption1") int bannerOption1,
                           @SessionAttribute(value = "verificationCode", required = false) String correctCode,
                           Model model,
                           HttpSession session,
                           RedirectAttributes redirectAttributes) {

        String errorMsg = validateForm(password, repeatPassword, phone, email, verificationCode, correctCode);

        if (errorMsg != null) {
            model.addAttribute("signOnMsg", errorMsg);
            return "account/register"; // 返回 Thymeleaf 视图 register.html
        }

        // 创建用户

        createAccount(firstName,lastName,address1,address2,city,zip,country,username, password, email, phone,state,favouriteCategoryId,listOption1,bannerOption1);
        String msg = validate(loginAccount.getPassword(), repeatPassword);
        if (msg != null) {
            redirectAttributes.addFlashAttribute("signOnMsg", msg);
            return "redirect:/account/register";
        }

        if (!validateVerificationCode(verificationCode, session)) {
            redirectAttributes.addFlashAttribute("signOnMsg", "验证码输入错误！");
            return "redirect:/account/register";
        }

        loginAccount.setStatus("OK");
        //accountService.insertAccount(loginAccount);
        createCoupon(loginAccount.getUsername());

        return "redirect:/common/countDownToLogin";
    }

    private String validateForm(String password, String repeatPassword, String phone, String email, String verificationCode, String correctCode) {
        if (password.length() < 8) {
            return "密码至少为8位！";
        }
        if (!isPasswordValid(password)) {
            return "密码须同时包含数字和字母！";
        }
        if (!password.equals(repeatPassword)) {
            return "两次输入的密码不一致！";
        }
        if (!(phone.length() == 11 && isPhoneValid(phone))) {
            return "手机号码格式不正确！";
        }
        if (!isEmailValid(email)) {
            return "邮箱格式不正确！";
        }
        if (verificationCode == null || !verificationCode.equalsIgnoreCase(correctCode)) {
            return "验证码输入错误！";
        }
        return null;
    }

    private boolean isPasswordValid(String password) {
        String patternStr = "^(?=.*[A-Za-z])(?=.*\\d).+$";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(password);
        return matcher.find();
    }

    private boolean isPhoneValid(String phone) {
        return phone.matches("\\d{11}"); // 11位数字
    }

    private boolean isEmailValid(String email) {
        String regex = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
        return email.matches(regex);
    }

    private void createAccount(String firstname,String lastname,String add1,String add2,String city,String zip,String country,String username, String password, String email, String phone,String state,String favouriteCategoryId,int listOption1,int bannerOption1) {
        AccountVO account = new AccountVO();

        account.setFirstName(firstname);
        account.setLastName(lastname);
        account.setAddress1(add1);
        account.setAddress2(add2);
        account.setCity(city);

        account.setZip(zip);
        account.setCountry(country);


        account.setUsername(username);
        account.setPassword(password);
        account.setEmail(email);
        account.setPhone(phone);
        account.setStatus("OK");
        account.setState(state);
        account.setFavouriteCategory(favouriteCategoryId);
        account.setBannerOption(bannerOption1);
        account.setListOption(listOption1);
        accountService.insertAccount(account);
        createCoupon(username);
    }

    private String validate(String password, String repeatPassword) {
        if (password.length() < 8) return "密码至少为8位！";
        if (!password.matches("^(?=.*[A-Za-z])(?=.*\\d).+$")) return "密码须同时包含数字和字母！";
        if (!password.equals(repeatPassword)) return "两次输入的密码不一致！";
        return null;
    }

    private boolean validateVerificationCode(String verificationCode, HttpSession session) {
        String correctCode = (String) session.getAttribute("verificationCode");
        return verificationCode != null && verificationCode.equalsIgnoreCase(correctCode);
    }

    private void createCoupon(String username) {
        Random random = new Random();
        for (int i = 0; i < 2; i++) {
            CouponPackage coupon = new CouponPackage();
            coupon.setCouponId(random.nextInt(5) + 1);
            coupon.setUsername(username);
            couponService.insertCoupon(coupon);
        }
    }

    @GetMapping("/signOn")
    public String signOn(Model model) {
        // 避免 Thymeleaf 解析 `null` 变量
        if (!model.containsAttribute("signOnMsg")) {
            model.addAttribute("signOnMsg", "");
        }
        if (!model.containsAttribute("username")) {
            model.addAttribute("username", "");
        }
        return "account/signon";
    }

    // 校验用户名和密码
    private boolean validate(String username, String password, Model model) {
        if (username == null || username.isEmpty()) {
            model.addAttribute("signOnMsg", "用户名不能为空");
            return false;
        }
        if (password == null || password.isEmpty()) {
            model.addAttribute("signOnMsg", "密码不能为空");
            return false;
        }
        return true;
    }

    // 校验验证码
    private boolean ifVerificationCode(String verificationCode, HttpSession session, Model model) {
        String correctCode = (String) session.getAttribute("verificationCode");
        if (verificationCode != null) {
            if (verificationCode.equalsIgnoreCase(correctCode)) {
                return true;
            } else {
                model.addAttribute("signOnMsg", "验证码输入错误！");
                return false;
            }
        }
        model.addAttribute("signOnMsg", "请输入验证码！");
        return false;
    }

    @PostMapping("/signOn")
    public String signOn(@RequestParam String username,
                         @RequestParam String password,
                         @RequestParam String verificationCode,
                         HttpSession session,
                         RedirectAttributes redirectAttributes,
                         Model model) {

        // 校验用户名和密码的正确性
        if (!validate(username, password,model)) {
            return "redirect:/account/signOn";
        }

        // 校验验证码
        if (!ifVerificationCode(verificationCode, session, model)) {
            model.addAttribute("user", username);
            model.addAttribute("pass", password);
            return "redirect:/account/signOn";
        }

        // 账户验证
        AccountVO loginAccount = accountService.getAccount(username, password);
        if (loginAccount == null) {
            model.addAttribute("signOnMsg", "用户名或密码错误");
            return "redirect:/account/signOn";
        }

        // 设置 Session 属性
        session.setAttribute("loginAccount", loginAccount);
        session.setAttribute("cart", new Cart());

        // 如果用户有收藏类别，则加载相关产品列表
        if (loginAccount.getBannerOption()==1) {
            IncludeMyListVO myList = catalogService.getIncludeMyList(loginAccount.getUsername());
            session.setAttribute("myList", myList);
        }
        return "redirect:/catalog/index";
    }

    @GetMapping("/couponForm")
    public String showCouponForm(@RequestParam("username") String username, Model model) {
        CouponPackageVO couponPackageVO = couponService.searchCouponByUsername(username);

        List<CouponPackage>couponPackages=couponPackageVO.getCouponList();

        // **转换 CouponPackage -> Coupon**
        List<Coupon> couponList = couponPackages.stream()
                .map(couponPackage -> couponService.searchCouponByID(couponPackage.getCouponId()))
                .toList();

        model.addAttribute("couponList", couponList);
        return "account/coupon"; // 对应 `/WEB-INF/jsp/account/coupon.jsp`
    }

    @GetMapping("/log")
    public String logHistory(
            @SessionAttribute(value = "loginAccount", required = false) AccountVO loginAccount,
            Model model, HttpSession session) {

        if (loginAccount == null) {
            return "redirect:/login"; // 如果未登录，跳转到登录页
        }

        String username = loginAccount.getUsername();
        System.out.println("History Account: " + loginAccount);
        System.out.println("History Account name: " + username);

        List<Log> logList = logService.searchHistory(username);
        Collections.reverse(logList);

        session.setAttribute("logList", logList);
        model.addAttribute("logList", logList);
        return "account/log";  // 直接返回 Thymeleaf 视图
    }
}
